home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Textfiles / zines / Phrack / Phrack Issue 52.sit / Phrack52 / 52 / P52-06 < prev    next >
Text File  |  1998-01-26  |  41KB  |  1,124 lines

  1. ---[  Phrack Magazine   Volume 8, Issue 52 January 26, 1998, article 06 of 20
  2.  
  3.  
  4. -------------------------[  Hardening the Linux Kernel (series 2.0.x)
  5.  
  6.  
  7. --------[  route|daemon9 <route@infonexus.com>
  8.  
  9.  
  10.  
  11.  
  12. ----[  Introduction and Impetus
  13.  
  14.  
  15.     Linux.  The cutest Unix-like O/S alive today.  Everyone knows at least
  16. *one* person who has at least *one* Linux machine.  Linux, whatever your
  17. opinion of it, is out there, and is being used by more and more people.  Many
  18. of the people using Linux are using it in multi-user environments.  All of a
  19. sudden they find security to be a big issue.  This article is for those people.
  20.  
  21.     This article covers a few areas of potential insecurity in the Linux O/S
  22. and attempts to improve upon them.  It contains several security related
  23. kernel patches for the 2.0.x kernels (each has been tested successfully on the
  24. 2.0.3x kernels and most should work on older 2.0.x kernels; see each
  25. subsection for more info).
  26.  
  27.     These are kernel patches.  They do nothing for user-land security.  If you 
  28. can not set permissions and configure services correctly, you should not be
  29. running a Unix machine.
  30.  
  31.     These patches are not bugfixes.  They are preventative security fixes.
  32. They are intended to prevent possible problems and breaches of security from 
  33. occurring.  In some cases they can remove (or at least severely complicate) the 
  34. threat of many of today's most popular methods of attack.
  35.  
  36.     These patches are not really useful on a single-user machine.  They are
  37. really intended for a multi-user box.
  38.  
  39.     This article is for those of you who want better security out of your Linux
  40. O/S.  If you want to go a bit further, look into the POSIX.1e (POSIX 6) stuff. 
  41. POSIX.1e is a security model that basically separates identity and privilege.
  42. Effectively, it splits superuser privileges into different `capabilities`.
  43. Additionally, the Linux POSIX.1e (linux-privs) implementation offers a bitmapped 
  44. securelevel, kernel-based auditing (userland audit hooks are being developed), 
  45. and ACLs. See: http://parc.power.net/morgan/Orange-Linux/linux-privs/index.html
  46.  
  47.     To sum it up, in this article, we explore a few ways to make the multi-user
  48. Linux machine a bit more secure and resilient to attack.
  49.  
  50.  
  51. ----[  The Patches
  52.  
  53.  
  54. procfs patch
  55. ------------
  56. Tested on:  2.0.0 +
  57. Author:     route
  58.  
  59.     Why should we allow anyone to be able to view info on any process?
  60.  
  61.     Normally, /bin/ps can show process listing for every process in the 
  62. kernel's process table, regardless of ownership.  A non-privileged user can 
  63. see all the running processes on a system.  This can include information that 
  64. could be used in some forms of known / guessed PID-based attacks, not to 
  65. mention the obvious lack of privacy.  /bin/ps gets this process information by 
  66. reading the /proc filesystem.
  67.  
  68.     The /proc filesystem is a virtual filesystem interface into the O/S which 
  69. provides all kinds of good information including the status of various 
  70. portions of the running kernel and a list of currently running processes.  It 
  71. has a filesystem interface, which means it has file-system-like access
  72. controls.  As such, we can change the default access permissions on the inode
  73. from 555 to 500.
  74.  
  75.     And that's the patch.  We just change the permissions on the inode from
  76. S_IFDIR | S_IRUGO | S_IXUGO to S_IFDIR | S_IRUSR | S_IXUSR.
  77.  
  78.  
  79. trusted path execution patch
  80. ----------------------------
  81. Tested on:  2.0.0 +
  82. Author:     route (2.0.x version, original 1.x patch by merc)
  83.  
  84.     Why should we allow arbitrary programs execution rights?
  85.  
  86.     Consider this scenario:  You are the administrator of a multi-user Linux 
  87. machine.  All of a sudden there is a new bug in the Pentium(tm) processor!  
  88. As it happens, this bug causes the CPU to lock up entirely, requiring a cold
  89. reboot.  This bug is also exploitable by any user regardless of privilege.  All
  90. it necessitates is for the malevolent user to 1) get the source, 2) compile the 
  91. exploit, and 3) execute the program.
  92.  
  93.     Whelp... 1) has happened.  You cannot prevent anyone from getting it.  It's
  94. out there.  You could remove permissions from the compiler on your machine or
  95. remove the binary entirely, but this does not stop the user from compiling 
  96. the exploit elsewhere, and getting the binary on your machine somehow.  You 
  97. cannot prevent 2) either.  However, if you only allow binaries to be executed 
  98. from a trusted path, you can prevent 3) from happening.  A trusted path is
  99. one that is inside is a root owned directory that is not group or world 
  100. writable.  /bin, /usr/bin, /usr/local/bin, are (under normal circumstances) 
  101. considered trusted.  Any non-root users home directory is not trusted, nor is
  102. /tmp.  Be warned:  This patch is a major annoyance to users who like to execute
  103. code and scripts from their home directories!  It will make you extremely 
  104. un-popular as far as these people are concerned.  It will also let you sleep
  105. easier at night knowing that no unscrupulous persons will be executing 
  106. malicious bits of code on your machine.
  107.  
  108.     Before any call to exec is allowed to run, we open the inode of the
  109. directory that the executable lives in and check ownership and permissions.
  110. If the directory is not owned by root, or is writable to group or other, we
  111. consider that untrusted.
  112.  
  113.  
  114. securelevel patch
  115. -----------------
  116. Tested on:  2.0.26 +
  117. Author:     route
  118.  
  119.     Damnit, if I set the immutable and append only bits, I did it for a reason.
  120.  
  121.     This patch isn't really much of a patch.  It simply bumps the securelevel
  122. up, to 1 from 0.  This freezes the immutable and append-only bits on files,
  123. keeping anyone from changing them (from the normal chattr interface).  Before
  124. turning this on, you should of course make certain key files immutable, and
  125. logfiles append-only.  It is still possible to open the raw disk device,
  126. however.  Your average cut and paste hacker will probably not know how to do
  127. this.
  128.     
  129.  
  130. stack execution disabling patch and symlink patch
  131. -------------------------------
  132. Tested on:  2.0.30 +
  133. Author:     solar designer
  134.  
  135.     From the documentation accompanying SD's patch:
  136.  
  137. This patch is intended to add protection against two classes of security
  138. holes: buffer overflows and symlinks in /tmp.
  139.  
  140. Most buffer overflow exploits are based on overwriting a function's return
  141. address on the stack to point to some arbitrary code, which is also put
  142. onto the stack. If the stack area is non-executable, buffer overflow
  143. vulnerabilities become harder to exploit.
  144.  
  145. Another way to exploit a buffer overflow is to point the return address to
  146. a function in libc, usually system(). This patch also changes the default
  147. address that shared libraries are mmap()ed at to make it always contain a
  148. zero byte. This makes it impossible to specify any more data (parameters
  149. to the function, or more copies of the return address when filling with a
  150. pattern) in an exploit that has to do with ASCIIZ strings (this is the
  151. case for most overflow vulnerabilities).
  152.  
  153. However, note that this patch is by no means a complete solution, it just
  154. adds an extra layer of security. Some buffer overflow vulnerabilities will
  155. still remain exploitable a more complicated way. The reason for using such
  156. a patch is to protect against some of the buffer overflow vulnerabilities
  157. that are yet unknown.
  158.  
  159. In this version of my patch I also added a symlink security fix, originally
  160. by Andrew Tridgell. I changed it to prevent from using hard links too, by
  161. simply not allowing non-root users to create hard links to files they don't
  162. own, in +t directories. This seems to be the desired behavior anyway, since
  163. otherwise users couldn't remove such links they just created. I also added
  164. exploit attempt logging, this code is shared with the non-executable stack
  165. stuff, and was the reason to make it a single patch instead of two separate
  166. ones. You can enable them separately anyway.
  167.  
  168.  
  169. GID split privilege patch
  170. -------------------------------
  171. Tested on:  2.0.30 +
  172. Author:     Original version DaveG, updated for 2.0.33 by route
  173.  
  174.     From the documentation accompanying Dave's original patch:
  175. This is a simple kernel patch that allows you to perform certain
  176. privileged operations with out requiring root access.  With this patch
  177. three groups become privileged groups allowed to do different operations
  178. within the kernel.
  179.  
  180. GID 16 : a program running with group 16 privileges can bind to a
  181.          < 1024.  This allows programs like: rlogin, rcp, rsh, and ssh
  182.          to run setgid 16 instead of setuid 0(root).  This also allows
  183.          servers that need to run as root to bind to a privileged port
  184.          like named, to also run setgid 16.
  185.  
  186. GID 17 : any program running under GID 17 privileges will be able to
  187.          create a raw socket.  Programs like ping and traceroute can now
  188.          be made to run setgid 17 instead of setuid 0(root).
  189.  
  190. GID 18 : This group is for SOCK_PACKET.  This isn't useful for most people,
  191.          so if you don't know what it is, don't worry about it.
  192.  
  193. Limitations
  194. -----------
  195. Since this is a simple patch, it is VERY limited.  First of all, there
  196. is no support for supplementary groups.  This means that you can't stack
  197. these privileges.  If you need GID 16 and 17, there isn't much you can do
  198. about it.
  199.  
  200.  
  201.  
  202. ----[  Installation 
  203.  
  204.  
  205.     This patchfile has been tested and verified to work against the latest
  206. stable release of the linux kernel (as of this writing, 2.0.33).  It should
  207. work against other 2.0.x releases as well with little or no modification.  THIS
  208. IS NOT A GUARANTEE!  Please do not send me your failed patch logs from older
  209. kernels.  Take this as a perfect opportunity to upgrade your kernel to the
  210. latest release.  Note that several of these patches are for X86-Linux only.
  211. Sorry.
  212.  
  213. 1.  Create the symlink:
  214.  
  215.         `cd /usr/src`
  216.         `ln -s linux-KERNEL_VERSION linux-stock`
  217.  
  218. 2.  Apply the kernel patch:
  219.  
  220.         `patch < slinux.patch >& patch.err`
  221.  
  222. 2a. Examine the error file for any failed hunks.  Figure where you went wrong
  223.     in life:
  224.  
  225.         `grep fail patch.err`
  226.  
  227. 3.  Configure your kernel:
  228.  
  229.         `make config` OR `make menu-config` OR `make xconfig`
  230.  
  231. 4.  You will need to enable prompting for experimental code in your kernel and
  232.     turn on the patches individually.
  233.  
  234. 5.  To configure the split GID privilege patch, add the follow to your
  235.     /etc/group file:
  236.  
  237.         `cat >> /etc/group`
  238.           priv_port::16:user1, user2, user3
  239.           raw_sock::17:user1, user2
  240.           sock_pak::18:user2, user3
  241.         ^D
  242.  
  243.     Where `userx` are the usernames of the users you wish to give these
  244.     permissions to.  Next, fix the corresponding group and permissions on the 
  245.     binaries you wish to strip root privileges from:
  246.  
  247.         `chgrp raw_sock /bin/ping`
  248.         `chmod 2755 /bin/ping`
  249.  
  250.  
  251.  
  252. ----[  The patchfile
  253.  
  254.  
  255.     This patchfile should be extracted with the Phrack Magazine Extraction
  256. Utility included in this (and every) issue.
  257.  
  258. <++> slinux.patch
  259. diff -ru linux-stock/Documentation/Configure.help linux-patched/Documentation/Configure.help
  260. --- linux-stock/Documentation/Configure.help    Fri Sep  5 20:43:58 1997
  261. +++ linux-patched/Documentation/Configure.help    Mon Nov 10 22:02:36 1997
  262. @@ -720,6 +720,77 @@
  263.    later load the module when you install the JDK or find an interesting
  264.    Java program that you can't live without.
  265.  
  266. +Non-executable user stack area (EXPERIMENTAL)
  267. +CONFIG_STACKEXEC
  268. +  Most buffer overflow exploits are based on overwriting a function's
  269. +  return address on the stack to point to some arbitrary code, which is
  270. +  also put onto the stack. If the stack area is non-executable, buffer
  271. +  overflow vulnerabilities become harder to exploit. However, a few
  272. +  programs depend on the stack being executable, and might stop working
  273. +  unless you also enable GCC trampolines autodetection below, or enable
  274. +  the stack area execution permission for every such program separately
  275. +  using chstk.c. If you don't know what all this is about, or don't care
  276. +  about security that much, say N.
  277. +
  278. +Autodetect GCC trampolines
  279. +CONFIG_STACKEXEC_AUTOENABLE
  280. +  GCC generates trampolines on the stack to correctly pass control to
  281. +  nested functions when calling from outside. This requires the stack
  282. +  being executable. When this option is enabled, programs containing
  283. +  trampolines will automatically get their stack area executable when
  284. +  a trampoline is found. However, in some cases this autodetection can
  285. +  be fooled in a buffer overflow exploit, so it is more secure to
  286. +  disable this option and use chstk.c to enable the stack area execution
  287. +  permission for every such program separately. If you're too lazy,
  288. +  answer Y.
  289. +
  290. +Log buffer overflow exploit attempts
  291. +CONFIG_STACKEXEC_LOG
  292. +  This option enables logging of buffer overflow exploit attempts. No
  293. +  more than one attempt per minute is logged, so this is safe. Say Y.
  294. +
  295. +Process table viewing restriction (EXPERIMENTAL)
  296. +CONFIG_PROC_RESTRICT
  297. +  This option enables process table viewing restriction.  Users will only
  298. +  be able to get status of processes they own, with the exception the 
  299. +  root user, who can get an entire process table listing.  This patch
  300. +  should not cause any problems with other programs but it is not fully
  301. +  tested under every possible contingency.  You must enable the /proc 
  302. +  filesystem for this option to be of any use.  If you run a multi-user
  303. +  system and are reasonably concerned with privacy and/or security, say Y.
  304. +
  305. +Trusted path execution (EXPERIMENTAL)
  306. +CONFIG_TPE
  307. +  This option enables trusted path execution.  Binaries are considered
  308. +  `trusted` if they live in a root owned directory that is not group or
  309. +  world writable.  If an attempt is made to execute a program from a non
  310. +  trusted directory, it will simply not be allowed to run.  This is 
  311. +  quite useful on a multi-user system where security is an issue.  Users
  312. +  will not be able to compile and execute arbitrary programs (read: evil)
  313. +  from their home directories, as these directories are not trusted.  
  314. +  This option is useless on a single user machine.
  315. +
  316. +Trusted path execution (EXPERIMENTAL)
  317. +CONFIG_TPE_LOG
  318. +  This option enables logging of execution attempts from non-trusted
  319. +  paths.
  320. +  
  321. +Secure mode (EXPERIMENTAL)
  322. +CONFIG_SECURE_ON
  323. +  This bumps up the securelevel from 0 to 1.  When the securelevel is `on`,
  324. +  immutable and append-only bits cannot be set or cleared.  If you are not
  325. +  concerned with security, you can say `N`.
  326. +
  327. +Split Network Groups (EXPERIMENTAL)
  328. +CONFIG_SPLIT_GID  
  329. +  This is a simple kernel patch that allows you to perform certain
  330. +  privileged operations with out requiring root access.  With this patch
  331. +  three groups become privileged groups allowed to do different operations
  332. +  within the kernel.
  333. +  GID 16 allows programs to bind to privledged ports.
  334. +  GID 17 allows programs to open raw sockets.
  335. +  GID 18 allows programs to open sock packets.
  336. +
  337.  Processor type
  338.  CONFIG_M386
  339.    This is the processor type of your CPU. It is used for optimizing
  340. @@ -2951,6 +3020,27 @@
  341.    netatalk, new mars-nwe and other file servers. At the time of
  342.    writing none of these are available. So it's safest to say N here
  343.    unless you really know that you need this feature.
  344. +
  345. +Symlink security fix (EXPERIMENTAL)
  346. +CONFIG_SYMLINK_FIX
  347. +  A very common class of security hole on UNIX-like systems involves
  348. +  a malicious user creating a symbolic link in /tmp pointing at
  349. +  another user's file. When the victim then writes to that file they
  350. +  inadvertently write to the wrong file. Enabling this option fixes
  351. +  this class of hole by preventing a process from following a link
  352. +  which is in a +t directory unless they own the link. However, this
  353. +  fix does not affect links owned by root, since these could only be
  354. +  created by someone having root access already. To prevent someone
  355. +  from using a hard link instead, this fix does not allow non-root
  356. +  users to create hard links in a +t directory to files they don't
  357. +  own. Note that this fix might break things. Only say Y if security
  358. +  is more important.
  359. +
  360. +Log symlink exploit attempts
  361. +CONFIG_SYMLINK_LOG
  362. +  This option enables logging of symlink (and hard link) exploit
  363. +  attempts. No more than one attempt per minute is logged, so this is
  364. +  safe. Say Y.
  365.  
  366.  Minix fs support
  367.  CONFIG_MINIX_FS
  368. diff -ru linux-stock/arch/i386/config.in linux-patched/arch/i386/config.in
  369. --- linux-stock/arch/i386/config.in    Sun May 12 21:17:23 1996
  370. +++ linux-patched/arch/i386/config.in    Sun Nov  9 12:38:27 1997
  371. @@ -35,6 +35,15 @@
  372.  tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
  373.  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
  374.    tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
  375. +  bool 'Non-executable user stack area (EXPERIMENTAL)' CONFIG_STACKEXEC
  376. +  if [ "$CONFIG_STACKEXEC" = "y" ]; then
  377. +    bool '   Autodetect GCC trampolines' CONFIG_STACKEXEC_AUTOENABLE
  378. +    bool '   Log buffer overflow exploit attempts' CONFIG_STACKEXEC_LOG
  379. +  fi
  380. +    bool '   Restrict process table viewing (EXPERIMENTAL)' CONFIG_PROC_RESTRICT
  381. +    bool '   Trusted path execution (EXPERIMENTAL)' CONFIG_TPE
  382. +    bool '   Log untrusted path execution attempts (EXPERIMENTAL)' CONFIG_TPE_LOG
  383. +    bool '   Split Network GIDs (EXPERIMENTAL)' CONFIG_SPLIT_GID
  384.  fi
  385.  bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
  386.  
  387. diff -ru linux-stock/arch/i386/defconfig linux-patched/arch/i386/defconfig
  388. --- linux-stock/arch/i386/defconfig    Mon Sep 22 13:44:01 1997
  389. +++ linux-patched/arch/i386/defconfig    Sun Nov  9 12:38:23 1997
  390. @@ -24,6 +24,10 @@
  391.  CONFIG_SYSVIPC=y
  392.  CONFIG_BINFMT_AOUT=y
  393.  CONFIG_BINFMT_ELF=y
  394. +# CONFIG_STACKEXEC is not set
  395. +CONFIG_STACKEXEC_AUTOENABLE=y
  396. +CONFIG_STACKEXEC_LOG=y
  397. +CONFIG_SPLIT_GID=y
  398.  CONFIG_KERNEL_ELF=y
  399.  # CONFIG_M386 is not set
  400.  # CONFIG_M486 is not set
  401. @@ -134,6 +138,8 @@
  402.  # Filesystems
  403.  #
  404.  # CONFIG_QUOTA is not set
  405. +# CONFIG_SYMLINK_FIX is not set
  406. +CONFIG_SYMLINK_LOG=y 
  407.  CONFIG_MINIX_FS=y
  408.  # CONFIG_EXT_FS is not set
  409.  CONFIG_EXT2_FS=y
  410. @@ -143,6 +149,9 @@
  411.  # CONFIG_VFAT_FS is not set
  412.  # CONFIG_UMSDOS_FS is not set
  413.  CONFIG_PROC_FS=y
  414. +CONFIG_PROC_RESTRICT=y
  415. +CONFIG_TPE=y
  416. +CONFIG_TPE_LOG=y
  417.  CONFIG_NFS_FS=y
  418.  # CONFIG_ROOT_NFS is not set
  419.  # CONFIG_SMB_FS is not set
  420. diff -ru linux-stock/arch/i386/kernel/head.S linux-patched/arch/i386/kernel/head.S
  421. --- linux-stock/arch/i386/kernel/head.S    Tue Aug  5 09:19:53 1997
  422. +++ linux-patched/arch/i386/kernel/head.S    Sun Nov  9 00:55:50 1997
  423. @@ -400,10 +400,17 @@
  424.      .quad 0x0000000000000000    /* not used */
  425.      .quad 0xc0c39a000000ffff    /* 0x10 kernel 1GB code at 0xC0000000 */
  426.      .quad 0xc0c392000000ffff    /* 0x18 kernel 1GB data at 0xC0000000 */
  427. +#ifdef CONFIG_STACKEXEC
  428. +    .quad 0x00cafa000000ffff    /* 0x23 user   2.75GB code at 0 */
  429. +    .quad 0x00cbf2000000ffff    /* 0x2b user   3GB data at 0 */
  430. +    .quad 0x00cbda000000ffff    /* 0x32 user   3GB code at 0, DPL=2 */
  431. +    .quad 0x00cbd2000000ffff    /* 0x3a user   3GB stack at 0, DPL=2 */
  432. +#else
  433.      .quad 0x00cbfa000000ffff    /* 0x23 user   3GB code at 0x00000000 */
  434.      .quad 0x00cbf2000000ffff    /* 0x2b user   3GB data at 0x00000000 */
  435.      .quad 0x0000000000000000    /* not used */
  436.      .quad 0x0000000000000000    /* not used */
  437. +#endif
  438.      .fill 2*NR_TASKS,8,0        /* space for LDT's and TSS's etc */
  439.  #ifdef CONFIG_APM
  440.      .quad 0x00c09a0000000000    /* APM CS    code */
  441. diff -ru linux-stock/arch/i386/kernel/ptrace.c linux-patched/arch/i386/kernel/ptrace.c
  442. --- linux-stock/arch/i386/kernel/ptrace.c    Mon Aug  4 12:12:22 1997
  443. +++ linux-patched/arch/i386/kernel/ptrace.c    Sun Nov  9 00:55:50 1997
  444. @@ -413,7 +413,7 @@
  445.                  addr == FS || addr == GS ||
  446.                  addr == CS || addr == SS) {
  447.                      data &= 0xffff;
  448. -                    if (data && (data & 3) != 3)
  449. +                    if (data && (data & 3) < 2)
  450.                      return -EIO;
  451.              }
  452.              if (addr == EFL) {   /* flags. */
  453. @@ -423,6 +423,10 @@
  454.            /* Do not allow the user to set the debug register for kernel
  455.               address space */
  456.            if(addr < 17){
  457. +            if (addr == EIP && (data & 0xF0000000) == 0xB0000000)
  458. +            if (put_stack_long(child, CS*sizeof(long)-MAGICNUMBER, USER_HUGE_CS) ||
  459. +                put_stack_long(child, SS*sizeof(long)-MAGICNUMBER, USER_HUGE_SS))
  460. +                return -EIO;
  461.                if (put_stack_long(child, sizeof(long)*addr-MAGICNUMBER, data))
  462.                  return -EIO;
  463.              return 0;
  464. diff -ru linux-stock/arch/i386/kernel/signal.c linux-patched/arch/i386/kernel/signal.c
  465. --- linux-stock/arch/i386/kernel/signal.c    Mon Aug  4 12:12:51 1997
  466. +++ linux-patched/arch/i386/kernel/signal.c    Sun Nov  9 00:55:50 1997
  467. @@ -83,10 +83,10 @@
  468.  #define COPY_SEG(x) \
  469.  if (   (context.x & 0xfffc)     /* not a NULL selectors */ \
  470.      && (context.x & 0x4) != 0x4 /* not a LDT selector */ \
  471. -    && (context.x & 3) != 3     /* not a RPL3 GDT selector */ \
  472. +    && (context.x & 3) < 2      /* not a RPL3 or RPL2 GDT selector */ \
  473.     ) goto badframe; COPY(x);
  474.  #define COPY_SEG_STRICT(x) \
  475. -if (!(context.x & 0xfffc) || (context.x & 3) != 3) goto badframe; COPY(x);
  476. +if (!(context.x & 0xfffc) || (context.x & 3) < 2) goto badframe; COPY(x);
  477.      struct sigcontext_struct context;
  478.      struct pt_regs * regs;
  479.  
  480. @@ -167,16 +167,20 @@
  481.      unsigned long * frame;
  482.  
  483.      frame = (unsigned long *) regs->esp;
  484. -    if (regs->ss != USER_DS && sa->sa_restorer)
  485. +    if (regs->ss != USER_DS && regs->ss != USER_HUGE_SS && sa->sa_restorer)
  486.          frame = (unsigned long *) sa->sa_restorer;
  487.      frame -= 64;
  488.      if (verify_area(VERIFY_WRITE,frame,64*4))
  489.          do_exit(SIGSEGV);
  490.  
  491.  /* set up the "normal" stack seen by the signal handler (iBCS2) */
  492. +#ifdef CONFIG_STACKEXEC
  493. +    put_user((unsigned long)MAGIC_SIGRETURN, frame);
  494. +#else
  495.  #define __CODE ((unsigned long)(frame+24))
  496.  #define CODE(x) ((unsigned long *) ((x)+__CODE))
  497.      put_user(__CODE,frame);
  498. +#endif
  499.      if (current->exec_domain && current->exec_domain->signal_invmap)
  500.          put_user(current->exec_domain->signal_invmap[signr], frame+1);
  501.      else
  502. @@ -204,19 +208,17 @@
  503.  /* non-iBCS2 extensions.. */
  504.      put_user(oldmask, frame+22);
  505.      put_user(current->tss.cr2, frame+23);
  506. +#ifndef CONFIG_STACKEXEC
  507.  /* set up the return code... */
  508.      put_user(0x0000b858, CODE(0));    /* popl %eax ; movl $,%eax */
  509.      put_user(0x80cd0000, CODE(4));    /* int $0x80 */
  510.      put_user(__NR_sigreturn, CODE(2));
  511.  #undef __CODE
  512.  #undef CODE
  513. +#endif
  514.  
  515.      /* Set up registers for signal handler */
  516. -    regs->esp = (unsigned long) frame;
  517. -    regs->eip = (unsigned long) sa->sa_handler;
  518. -    regs->cs = USER_CS; regs->ss = USER_DS;
  519. -    regs->ds = USER_DS; regs->es = USER_DS;
  520. -    regs->gs = USER_DS; regs->fs = USER_DS;
  521. +    start_thread(regs, (unsigned long)sa->sa_handler, (unsigned long)frame);
  522.      regs->eflags &= ~TF_MASK;
  523.  }
  524.  
  525. diff -ru linux-stock/arch/i386/kernel/traps.c linux-patched/arch/i386/kernel/traps.c
  526. --- linux-stock/arch/i386/kernel/traps.c    Mon Aug 11 13:37:24 1997
  527. +++ linux-patched/arch/i386/kernel/traps.c    Sun Nov  9 00:55:50 1997
  528. @@ -117,7 +117,7 @@
  529.  
  530.      esp = (unsigned long) ®s->esp;
  531.      ss = KERNEL_DS;
  532. -    if ((regs->eflags & VM_MASK) || (3 & regs->cs) == 3)
  533. +    if ((regs->eflags & VM_MASK) || (3 & regs->cs) >= 2)
  534.          return;
  535.      if (regs->cs & 3) {
  536.          esp = regs->esp;
  537. @@ -193,11 +193,82 @@
  538.  
  539.  asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
  540.  {
  541. +#ifdef CONFIG_STACKEXEC
  542. +    unsigned long retaddr;
  543. +#endif
  544. +
  545.      if (regs->eflags & VM_MASK) {
  546.          handle_vm86_fault((struct vm86_regs *) regs, error_code);
  547.          return;
  548.      }
  549. +
  550. +#ifdef CONFIG_STACKEXEC
  551. +/* Check if it was return from a signal handler */
  552. +    if (regs->cs == USER_CS || regs->cs == USER_HUGE_CS)
  553. +    if (get_seg_byte(USER_DS, (char *)regs->eip) == 0xC3)
  554. +    if (!verify_area(VERIFY_READ, (void *)regs->esp, 4))
  555. +    if ((retaddr = get_seg_long(USER_DS, (char *)regs->esp)) ==
  556. +        MAGIC_SIGRETURN) {
  557. +/*
  558. + * Call sys_sigreturn() to restore the context. It would definitely be better
  559. + * to convert sys_sigreturn() into an inline function accepting a pointer to
  560. + * pt_regs, making this faster...
  561. + */
  562. +        regs->esp += 8;
  563. +        __asm__("movl %3,%%esi;"
  564. +            "subl %1,%%esp;"
  565. +            "movl %2,%%ecx;"
  566. +            "movl %%esp,%%edi;"
  567. +            "cld; rep; movsl;"
  568. +            "call sys_sigreturn;"
  569. +            "leal %3,%%edi;"
  570. +            "addl %1,%%edi;"
  571. +            "movl %%esp,%%esi;"
  572. +            "movl (%%edi),%%edi;"
  573. +            "movl %2,%%ecx;"
  574. +            "cld; rep; movsl;"
  575. +            "movl %%esi,%%esp"
  576. +        :
  577. +/* %eax is returned separately */
  578. +        "=a" (regs->eax)
  579. +        :
  580. +        "i" (sizeof(*regs)),
  581. +        "i" (sizeof(*regs) >> 2),
  582. +        "m" (regs)
  583. +        :
  584. +        "cx", "dx", "si", "di", "cc", "memory");
  585. +        return;
  586. +    }
  587. +
  588. +#ifdef CONFIG_STACKEXEC_LOG
  589. +/*
  590. + * Check if we're returning to the stack area, which is only likely to happen
  591. + * when attempting to exploit a buffer overflow.
  592. + */
  593. +    else if (regs->cs == USER_CS &&
  594. +        (retaddr & 0xF0000000) == 0xB0000000)
  595. +        security_alert("buffer overflow");
  596. +#endif
  597. +#endif
  598. +
  599.      die_if_kernel("general protection",regs,error_code);
  600. +
  601. +#if defined(CONFIG_STACKEXEC) && defined(CONFIG_STACKEXEC_AUTOENABLE)
  602. +/*
  603. + * Switch to the original huge code segment (and allow code execution on the
  604. + * stack for this entire process), if the faulty instruction is a call %reg,
  605. + * except for call %esp.
  606. + */
  607. +    if (regs->cs == USER_CS)
  608. +    if (get_seg_byte(USER_DS, (char *)regs->eip) == 0xFF &&
  609. +        (get_seg_byte(USER_DS, (char *)(regs->eip + 1)) & 0xD8) == 0xD0 &&
  610. +        get_seg_byte(USER_DS, (char *)(regs->eip + 1)) != 0xD4) {
  611. +        current->flags |= PF_STACKEXEC;
  612. +        regs->cs = USER_HUGE_CS; regs->ss = USER_HUGE_SS;
  613. +        return;
  614. +    }
  615. +#endif
  616. +
  617.      current->tss.error_code = error_code;
  618.      current->tss.trap_no = 13;
  619.      force_sig(SIGSEGV, current);    
  620. diff -ru linux-stock/arch/i386/mm/fault.c linux-patched/arch/i386/mm/fault.c
  621. --- linux-stock/arch/i386/mm/fault.c    Sat Aug 16 22:21:20 1997
  622. +++ linux-patched/arch/i386/mm/fault.c    Sun Nov  9 00:55:50 1997
  623. @@ -44,6 +44,7 @@
  624.      unsigned long page;
  625.      int write;
  626.  
  627. +    if ((regs->cs & 3) >= 2) error_code |= 4;
  628.      /* get the address */
  629.      __asm__("movl %%cr2,%0":"=r" (address));
  630.      down(&mm->mmap_sem);
  631. diff -ru linux-stock/fs/binfmt_aout.c linux-patched/fs/binfmt_aout.c
  632. --- linux-stock/fs/binfmt_aout.c    Wed Oct 15 14:56:43 1997
  633. +++ linux-patched/fs/binfmt_aout.c    Tue Nov 11 00:38:48 1997
  634. @@ -315,6 +315,7 @@
  635.      current->suid = current->euid = current->fsuid = bprm->e_uid;
  636.      current->sgid = current->egid = current->fsgid = bprm->e_gid;
  637.       current->flags &= ~PF_FORKNOEXEC;
  638. +        if (N_FLAGS(ex) & F_STACKEXEC) current->flags |= PF_STACKEXEC;
  639.      if (N_MAGIC(ex) == OMAGIC) {
  640.  #ifdef __alpha__
  641.          do_mmap(NULL, N_TXTADDR(ex) & PAGE_MASK,
  642. diff -ru linux-stock/fs/binfmt_elf.c linux-patched/fs/binfmt_elf.c
  643. --- linux-stock/fs/binfmt_elf.c    Wed Oct 15 14:56:43 1997
  644. +++ linux-patched/fs/binfmt_elf.c    Tue Nov 11 01:02:05 1997
  645. @@ -55,7 +55,10 @@
  646.  #define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
  647.  #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
  648.  
  649. -static struct linux_binfmt elf_format = {
  650. +#ifndef CONFIG_STACKEXEC
  651. +static
  652. +#endif
  653. +struct linux_binfmt elf_format = {  
  654.  #ifndef MODULE
  655.      NULL, NULL, load_elf_binary, load_elf_library, elf_core_dump
  656.  #else
  657. @@ -662,6 +665,7 @@
  658.      current->suid = current->euid = current->fsuid = bprm->e_uid;
  659.      current->sgid = current->egid = current->fsgid = bprm->e_gid;
  660.      current->flags &= ~PF_FORKNOEXEC;
  661. +        if (elf_ex.e_flags & EF_STACKEXEC) current->flags |= PF_STACKEXEC;
  662.      bprm->p = (unsigned long) 
  663.        create_elf_tables((char *)bprm->p,
  664.              bprm->argc,
  665. diff -ru linux-stock/fs/exec.c linux-patched/fs/exec.c
  666. --- linux-stock/fs/exec.c    Wed Oct 15 14:56:43 1997
  667. +++ linux-patched/fs/exec.c    Tue Nov 11 12:59:51 1997
  668. @@ -475,6 +475,8 @@
  669.      }
  670.      current->comm[i] = '\0';
  671.  
  672. +        current->flags &= ~PF_STACKEXEC;
  673. +
  674.      /* Release all of the old mmap stuff. */
  675.      if (exec_mmap())
  676.          return -ENOMEM;
  677. @@ -650,12 +652,30 @@
  678.  int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
  679.  {
  680.      struct linux_binprm bprm;
  681. +        struct inode *dir;
  682. +        const char *basename;
  683. +        int namelen;
  684.      int retval;
  685.      int i;
  686.  
  687.      bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
  688.      for (i=0 ; i<MAX_ARG_PAGES ; i++)    /* clear page-table */
  689.          bprm.page[i] = 0;
  690. +    
  691. +#ifdef  CONFIG_TPE
  692. +        /* Check to make sure the path is trusted.  If the directory is root
  693. +         * owned and not group/world writable, it's trusted.  Otherwise, 
  694. +         * return -EACCES and optionally log it
  695. +         */
  696. +        dir_namei(filename, &namelen, &basename, NULL, &dir);
  697. +        if (dir->i_mode & (S_IWGRP | S_IWOTH) || dir->i_uid)
  698. +        {
  699. +#ifdef  CONFIG_TPE_LOG
  700. +            security_alert("Trusted path execution violation");
  701. +#endif  /* CONFIG_TPE_LOG */
  702. +            return -EACCES;
  703. +        }
  704. +#endif  /* CONFIG_TPE */
  705.      retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
  706.      if (retval)
  707.          return retval;
  708. diff -ru linux-stock/fs/namei.c linux-patched/fs/namei.c
  709. --- linux-stock/fs/namei.c    Sat Aug 16 16:23:19 1997
  710. +++ linux-patched/fs/namei.c    Tue Nov 11 00:44:51 1997
  711. @@ -19,6 +19,7 @@
  712.  #include <linux/fcntl.h>
  713.  #include <linux/stat.h>
  714.  #include <linux/mm.h>
  715. +#include <linux/config.h>
  716.  
  717.  #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
  718.  
  719. @@ -207,6 +208,23 @@
  720.          *res_inode = inode;
  721.          return 0;
  722.      }
  723. +#ifdef CONFIG_SYMLINK_FIX
  724. +/*
  725. + * Don't follow links that we don't own in +t directories, unless the link
  726. + * is owned by root.
  727. + */
  728. +        if (S_ISLNK(inode->i_mode) && (dir->i_mode & S_ISVTX) &&
  729. +            inode->i_uid &&
  730. +            current->fsuid != inode->i_uid) {
  731. +#ifdef CONFIG_SYMLINK_LOG
  732. +                security_alert("symlink");
  733. +#endif
  734. +                iput(dir);
  735. +                iput(inode);
  736. +                *res_inode = NULL;
  737. +                return -EPERM;
  738. +        }
  739. +#endif
  740.      return inode->i_op->follow_link(dir,inode,flag,mode,res_inode);
  741.  }
  742.  
  743. @@ -216,8 +234,13 @@
  744.   * dir_namei() returns the inode of the directory of the
  745.   * specified name, and the name within that directory.
  746.   */
  747. +#ifdef  CONFIG_TPE
  748. +int dir_namei(const char *pathname, int *namelen, const char **name,
  749. +                     struct inode * base, struct inode **res_inode)
  750. +#else
  751.  static int dir_namei(const char *pathname, int *namelen, const char **name,
  752.                       struct inode * base, struct inode **res_inode)
  753. +#endif  /* CONFIG_TPE */
  754.  {
  755.      char c;
  756.      const char * thisname;
  757. @@ -787,6 +810,22 @@
  758.          iput(dir);
  759.          return -EPERM;
  760.      }
  761. +#ifdef CONFIG_SYMLINK_FIX
  762. +/*
  763. + * Don't allow non-root users to create hard links to files they don't own
  764. + * in a +t directory.
  765. + */
  766. +        if ((dir->i_mode & S_ISVTX) &&
  767. +            current->fsuid != oldinode->i_uid &&
  768. +            !fsuser()) {
  769. +#ifdef CONFIG_SYMLINK_LOG
  770. +                security_alert("hard link");
  771. +#endif
  772. +                iput(oldinode);
  773. +                iput(dir);
  774. +                return -EPERM;
  775. +        }
  776. +#endif
  777.      if (IS_RDONLY(dir)) {
  778.          iput(oldinode);
  779.          iput(dir);
  780. diff -ru linux-stock/fs/proc/base.c linux-patched/fs/proc/base.c
  781. --- linux-stock/fs/proc/base.c    Wed Feb 21 01:26:09 1996
  782. +++ linux-patched/fs/proc/base.c    Sun Nov  9 10:53:19 1997
  783. @@ -74,7 +74,11 @@
  784.   */
  785.  struct proc_dir_entry proc_pid = {
  786.      PROC_PID_INO, 5, "<pid>",
  787. -    S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
  788. +#ifdef  CONFIG_PROC_RESTRICT
  789. +        S_IFDIR | S_IRUSR | S_IXUSR, 2, 0, 0,
  790. +#else
  791. +        S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
  792. +#endif  /* CONFIG_PROC_RESTRICT */
  793.      0, &proc_base_inode_operations,
  794.      NULL, proc_pid_fill_inode,
  795.      NULL, &proc_root, NULL
  796. diff -ru linux-stock/fs/proc/inode.c linux-patched/fs/proc/inode.c
  797. --- linux-stock/fs/proc/inode.c    Sat Nov 30 02:21:21 1996
  798. +++ linux-patched/fs/proc/inode.c    Sun Nov  9 10:58:06 1997
  799. @@ -153,7 +153,11 @@
  800.      if (!p || i >= NR_TASKS)
  801.          return;
  802.      if (ino == PROC_ROOT_INO) {
  803. -        inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  804. +#ifdef  CONFIG_PROC_RESTRICT
  805. +                inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
  806. +#else
  807. +                inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  808. +#endif  /* CONFIG_PROC_RESTRICT */
  809.          inode->i_nlink = 2;
  810.          for (i = 1 ; i < NR_TASKS ; i++)
  811.              if (task[i])
  812. @@ -171,7 +175,11 @@
  813.                  inode->i_nlink = 2;
  814.                  break;
  815.              case PROC_SCSI:
  816. +#ifdef  CONFIG_PROC_RESTRICT
  817. +                                inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
  818. +#else
  819.                                  inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  820. +#endif  /* CONFIG_PROC_RESTRICT */
  821.                                  inode->i_nlink = 2;
  822.                                  inode->i_op = &proc_scsi_inode_operations;
  823.                                  break;
  824. @@ -181,7 +189,11 @@
  825.                  inode->i_size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
  826.                  break;
  827.              case PROC_PROFILE:
  828. -                inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR;
  829. +#ifdef  CONFIG_PROC_RESTRICT
  830. +                                inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
  831. +#else
  832. +                                inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  833. +#endif  /* CONFIG_PROC_RESTRICT */
  834.                  inode->i_op = &proc_profile_inode_operations;
  835.                  inode->i_size = (1+prof_len) * sizeof(unsigned long);
  836.                  break;
  837. @@ -203,7 +215,11 @@
  838.              return;
  839.          case PROC_PID_MEM:
  840.              inode->i_op = &proc_mem_inode_operations;
  841. -            inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
  842. +#ifdef  CONFIG_PROC_RESTRICT
  843. +                        inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
  844. +#else
  845. +                        inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  846. +#endif  /* CONFIG_PROC_RESTRICT */
  847.              return;
  848.          case PROC_PID_CWD:
  849.          case PROC_PID_ROOT:
  850. diff -ru linux-stock/include/asm-i386/processor.h linux-patched/include/asm-i386/processor.h
  851. --- linux-stock/include/asm-i386/processor.h    Tue Mar 11 13:52:29 1997
  852. +++ linux-patched/include/asm-i386/processor.h    Tue Nov 11 00:47:04 1997
  853. @@ -9,6 +9,8 @@
  854.  
  855.  #include <asm/vm86.h>
  856.  #include <asm/math_emu.h>
  857. +#include <linux/binfmts.h>
  858. +#include <linux/config.h>
  859.  
  860.  /*
  861.   * System setup and hardware bug flags..
  862. @@ -41,6 +43,15 @@
  863.   */
  864.  #define TASK_SIZE    (0xC0000000UL)
  865.  
  866. +#if defined(CONFIG_STACKEXEC) && defined(CONFIG_BINFMT_ELF)
  867. +extern struct linux_binfmt elf_format;
  868. +#define MMAP_ADDR ( \
  869. +    current->binfmt == &elf_format && \
  870. +    !(current->flags & PF_STACKEXEC) \
  871. +    ? 0x00110000UL \
  872. +    : TASK_SIZE / 3 )
  873. +#endif
  874. +
  875.  /*
  876.   * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  877.   */
  878. @@ -134,14 +145,6 @@
  879.  #define alloc_kernel_stack()    __get_free_page(GFP_KERNEL)
  880.  #define free_kernel_stack(page) free_page((page))
  881.  
  882. -static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
  883. -{
  884. -    regs->cs = USER_CS;
  885. -    regs->ds = regs->es = regs->ss = regs->fs = regs->gs = USER_DS;
  886. -    regs->eip = eip;
  887. -    regs->esp = esp;
  888. -}
  889. -
  890.  /*
  891.   * Return saved PC of a blocked thread.
  892.   */
  893. @@ -151,3 +154,25 @@
  894.  }
  895.  
  896.  #endif /* __ASM_I386_PROCESSOR_H */
  897. +
  898. +#if defined(current) && !defined(__START_THREAD)
  899. +#define __START_THREAD
  900. +
  901. +static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
  902. +{
  903. +#ifdef CONFIG_STACKEXEC
  904. +    if (current->flags & PF_STACKEXEC) {
  905. +        regs->cs = USER_HUGE_CS; regs->ss = USER_HUGE_SS;
  906. +    } else {
  907. +        regs->cs = USER_CS; regs->ss = USER_DS;
  908. +    }
  909. +    regs->ds = regs->es = regs->fs = regs->gs = USER_DS;
  910. +#else
  911. +    regs->cs = USER_CS;
  912. +    regs->ds = regs->es = regs->fs = regs->gs = regs->ss = USER_DS;
  913. +#endif
  914. +    regs->eip = eip;
  915. +    regs->esp = esp;
  916. +}
  917. +
  918. +#endif /* __START_THREAD */
  919. diff -ru linux-stock/include/asm-i386/segment.h linux-patched/include/asm-i386/segment.h
  920. --- linux-stock/include/asm-i386/segment.h    Tue Apr  9 00:35:29 1996
  921. +++ linux-patched/include/asm-i386/segment.h    Tue Nov 11 00:47:13 1997
  922. @@ -1,11 +1,27 @@
  923.  #ifndef _ASM_SEGMENT_H
  924.  #define _ASM_SEGMENT_H
  925.  
  926. +#include <linux/config.h>
  927. +
  928.  #define KERNEL_CS    0x10
  929.  #define KERNEL_DS    0x18
  930.  
  931.  #define USER_CS        0x23
  932.  #define USER_DS        0x2B
  933. +
  934. +#ifdef CONFIG_STACKEXEC
  935. +#define USER_HUGE_CS    0x32
  936. +#define USER_HUGE_SS    0x3A
  937. +#else
  938. +#define USER_HUGE_CS    0x23
  939. +#define USER_HUGE_SS    0x2B
  940. +#endif
  941. +
  942. +/*
  943. + * Magic address to return to the kernel from signal handlers, any address
  944. + * beyond user code segment limit will do.
  945. + */
  946. +#define MAGIC_SIGRETURN    0xC1428571
  947.  
  948.  #ifndef __ASSEMBLY__
  949.  
  950. diff -ru linux-stock/include/linux/a.out.h linux-patched/include/linux/a.out.h
  951. --- linux-stock/include/linux/a.out.h    Sat Aug 17 11:19:28 1996
  952. +++ linux-patched/include/linux/a.out.h    Tue Nov 11 00:47:21 1997
  953. @@ -37,6 +37,9 @@
  954.    M_MIPS2 = 152,    /* MIPS R6000/R4000 binary */
  955.  };
  956.  
  957. +/* Constants for the N_FLAGS field */
  958. +#define F_STACKEXEC    1    /* Executable stack area forced */
  959. +
  960.  #if !defined (N_MAGIC)
  961.  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
  962.  #endif
  963. diff -ru linux-stock/include/linux/elf.h linux-patched/include/linux/elf.h
  964. --- linux-stock/include/linux/elf.h    Sat Aug 10 00:03:15 1996
  965. +++ linux-patched/include/linux/elf.h    Tue Nov 11 00:47:39 1997
  966. @@ -57,6 +57,9 @@
  967.   */
  968.  #define EM_ALPHA    0x9026
  969.  
  970. +/* Constants for the e_flags field */
  971. +#define EF_STACKEXEC    1    /* Executable stack area forced */
  972. +
  973.  
  974.  /* This is the info that is needed to parse the dynamic section of the file */
  975.  #define DT_NULL        0
  976. diff -ru linux-stock/include/linux/kernel.h linux-patched/include/linux/kernel.h
  977. --- linux-stock/include/linux/kernel.h    Thu Aug 14 10:05:47 1997
  978. +++ linux-patched/include/linux/kernel.h    Tue Nov 11 00:47:44 1997
  979. @@ -78,6 +78,27 @@
  980.          (((addr) >> 16) & 0xff), \
  981.          (((addr) >> 24) & 0xff)
  982.  
  983. +#define security_alert(msg) { \
  984. +    static unsigned long warning_time = 0, no_flood_yet = 0; \
  985. +\
  986. +/* Make sure at least one minute passed since the last warning logged */ \
  987. +    if (!warning_time || jiffies - warning_time > 60 * HZ) { \
  988. +        warning_time = jiffies; no_flood_yet = 1; \
  989. +        printk( \
  990. +            KERN_ALERT \
  991. +            "Possible " msg " exploit attempt:\n" \
  992. +            KERN_ALERT \
  993. +            "Process %s (pid %d, uid %d, euid %d).\n", \
  994. +            current->comm, current->pid, \
  995. +            current->uid, current->euid); \
  996. +    } else if (no_flood_yet) { \
  997. +        warning_time = jiffies; no_flood_yet = 0; \
  998. +        printk( \
  999. +            KERN_ALERT \
  1000. +            "More possible " msg " exploit attempts follow.\n"); \
  1001. +    } \
  1002. +}
  1003. +
  1004.  #endif /* __KERNEL__ */
  1005.  
  1006.  #define SI_LOAD_SHIFT    16
  1007. diff -ru linux-stock/include/linux/sched.h linux-patched/include/linux/sched.h
  1008. --- linux-stock/include/linux/sched.h    Wed Oct 15 15:22:05 1997
  1009. +++ linux-patched/include/linux/sched.h    Tue Nov 11 00:47:48 1997
  1010. @@ -269,6 +269,8 @@
  1011.  #define PF_USEDFPU    0x00100000    /* Process used the FPU this quantum (SMP only) */
  1012.  #define PF_DTRACE    0x00200000    /* delayed trace (used on m68k) */
  1013.  
  1014. +#define PF_STACKEXEC    0x01000000    /* Executable stack area forced */
  1015. +
  1016.  /*
  1017.   * Limit the stack by to some sane default: root can always
  1018.   * increase this limit if needed..  8MB seems reasonable.
  1019. @@ -490,6 +492,9 @@
  1020.  
  1021.  #define for_each_task(p) \
  1022.      for (p = &init_task ; (p = p->next_task) != &init_task ; )
  1023. +
  1024. +/* x86 start_thread() */
  1025. +#include <asm/processor.h>
  1026.  
  1027.  #endif /* __KERNEL__ */
  1028.  
  1029. diff -ru linux-stock/kernel/sched.c linux-patched/kernel/sched.c
  1030. --- linux-stock/kernel/sched.c    Fri Oct 17 13:17:43 1997
  1031. +++ linux-patched/kernel/sched.c    Sun Nov  9 01:11:01 1997
  1032. @@ -44,7 +44,11 @@
  1033.   * kernel variables
  1034.   */
  1035.  
  1036. +#ifdef  CONFIG_SECURE_ON
  1037. +int securelevel = 1;            /* system security level */
  1038. +#else
  1039.  int securelevel = 0;            /* system security level */
  1040. +#endif
  1041.  
  1042.  long tick = (1000000 + HZ/2) / HZ;    /* timer interrupt period */
  1043.  volatile struct timeval xtime;        /* The current time */
  1044. diff -ru linux-stock/mm/mmap.c linux-patched/mm/mmap.c
  1045. --- linux-stock/mm/mmap.c    Fri Nov 22 06:25:17 1996
  1046. +++ linux-patched/mm/mmap.c    Tue Nov 11 00:48:26 1997
  1047. @@ -308,7 +308,11 @@
  1048.      if (len > TASK_SIZE)
  1049.          return 0;
  1050.      if (!addr)
  1051. +#ifdef MMAP_ADDR
  1052. +        addr = MMAP_ADDR;
  1053. +#else
  1054.          addr = TASK_SIZE / 3;
  1055. +#endif
  1056.      addr = PAGE_ALIGN(addr);
  1057.  
  1058.      for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
  1059.  
  1060.  
  1061. diff -ru linux-stock/net/ipv4/af_inet.c linux-patched/net/ipv4/af_inet.c
  1062. --- linux/net/ipv4/af_inet.c    Fri Aug 15 12:23:23 1997
  1063. +++ linux-stock/net/ipv4/af_inet.c    Mon Dec 29 18:05:29 1997
  1064. @@ -111,6 +111,15 @@
  1065.  
  1066.  #define min(a,b)    ((a)<(b)?(a):(b))
  1067.  
  1068. +#ifdef  CONFIG_SPLIT_GID
  1069. +/* 
  1070. + *  Priveleged group ids
  1071. + */
  1072. +#define PROT_SOCK_GID   16
  1073. +#define RAW_SOCK_GID    17
  1074. +#define PACKET_SOCK_GID 18
  1075. +#endif  /* CONFIG_SPLIT_GID */
  1076. +
  1077.  extern struct proto packet_prot;
  1078.  extern int raw_get_info(char *, char **, off_t, int, int);
  1079.  extern int snmp_get_info(char *, char **, off_t, int, int);
  1080. @@ -435,8 +444,26 @@
  1081.          sk->no_check = UDP_NO_CHECK;
  1082.          prot=&udp_prot;
  1083.      } else if(sock->type == SOCK_RAW || sock->type == SOCK_PACKET) {
  1084. +#ifdef  CONFIG_SPLIT_GID
  1085. +                /*
  1086. +                 *  If we are not the super user, check to see if we have the
  1087. +                 *  corresponding special group priviledge.
  1088. +                 */ 
  1089. +                if (!suser())
  1090. +                {
  1091. +                    if (sock->type == SOCK_RAW && current->egid != RAW_SOCK_GID)
  1092. +                    {
  1093. +                        goto free_and_badperm;
  1094. +                    }
  1095. +                    else if (sock->type == SOCK_PACKET && current->egid != PACKET_SOCK_GID)
  1096. +                    {
  1097. +                        goto free_and_badperm;
  1098. +                    }
  1099. +                }
  1100. +#else
  1101.          if (!suser()) 
  1102.              goto free_and_badperm;
  1103. +#endif  /* CONFIG_SPLIT_GID */
  1104.          if (!protocol) 
  1105.              goto free_and_noproto;
  1106.          prot = &raw_prot;
  1107. @@ -621,7 +648,11 @@
  1108.      if (snum == 0) 
  1109.          snum = sk->prot->good_socknum();
  1110.          if (snum < PROT_SOCK) {
  1111. +#ifdef  CONFIG_SPLIT_GID
  1112. +        if (!suser() && current->egid != PROT_SOCK_GID) 
  1113. +#else
  1114.          if (!suser()) 
  1115. +#endif  /* CONFIG_SPLIT_GID */
  1116.          return(-EACCES);
  1117.          if (snum == 0)
  1118.              return(-EAGAIN);
  1119. <-->
  1120.  
  1121.  
  1122. ----[  EOF
  1123.  
  1124.